// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: Apache-2.0

import type { EdgeKey, NodeInfo, EdgeInfo as RoadmapEdgeInfo, NodeInfo as RoadmapNodeInfo } from "$lib/api/proto/roadmap_data_api";
import { appStore } from "$lib/stores/app.svelte";
import { userStore } from "$lib/stores/user.svelte";
import { callApi } from "$lib/utils/call_utils";
import type { XYPosition } from "@xyflow/svelte";
import type { NodeType } from "./types";
import type { NodeStateInfo } from "$lib/api/proto/roadmap_data_state_api";
import type { RagConfig } from "$lib/api/proto/roadmap_rag_api";

class RoadmapStore {
    private _roadmapId = $state("");
    private _roadmapMode = $state(null as 'edit' | 'update' | 'view' | null);

    get roadmapId() {
        return this._roadmapId;
    }

    get roadmapMode() {
        return this._roadmapMode;
    }

    private _nodeList = $state([] as RoadmapNodeInfo[]);
    private _edgeList = $state([] as RoadmapEdgeInfo[]);
    private _selectNodeIdList = $state([] as string[]);

    private _nodeStateList = $state([] as NodeStateInfo[]);
    private _targetMemberUserId = $state("");

    get nodeList() {
        return this._nodeList;
    }

    get edgeList() {
        return this._edgeList;
    }

    get selectNodeIdList() {
        return this._selectNodeIdList;
    }

    get nodeStateList() {
        return this._nodeStateList;
    }

    get targetMemberUserId() {
        return this._targetMemberUserId;
    }

    addSelectNodeId(nodeId: string) {
        const index = this.nodeList.findIndex(item => item.nodeId == nodeId);
        if (index == -1) {
            return;
        }
        const tmpList = this._selectNodeIdList.slice();
        if (tmpList.includes(nodeId)) {
            return;
        }
        tmpList.push(nodeId);
        this._selectNodeIdList = tmpList;
    }

    removeSelectNodeId(nodeId: string) {
        if (this._selectNodeIdList.includes(nodeId)) {
            const tmpList = this._selectNodeIdList.filter(item => item != nodeId);
            this._selectNodeIdList = tmpList;
        }
    }


    public targetNodeType = $state(null as NodeType | null);
    public targetDropPosition = $state(null as XYPosition | null);
    public editNodeType = $state(null as NodeType | null);
    public editNode = $state(null as NodeInfo | null);

    public inConnect = $state(false);

    public editEdge = $state(null as EdgeKey | null);

    async init(roadmapId: string, roadmapMode: 'edit' | 'update' | 'view') {
        this._roadmapMode = roadmapMode;
        if (this._roadmapId != roadmapId) {
            this._roadmapId = roadmapId;
            await this.loadNodeList();
            await this.loadEdgeList();
            await this.loadRagConfigList();
        }

        if (roadmapMode == "update") {
            if (userStore.userInfo != null) {
                await this.loadNodeStateList(userStore.userInfo.userId);
            }
        } else {
            this._targetMemberUserId = "";
            this._nodeStateList = [];
        }
    }

    private async loadNodeList() {
        this._nodeList = [];
        if (userStore.userSession == null) {
            return;
        }
        const res = await callApi(appStore.roadmapDataApiClient.listNode({
            sessionId: userStore.userSession,
            roadmapId: this._roadmapId,
        }).response);
        this._nodeList = res.nodeList;
    }

    private async loadEdgeList() {
        this._edgeList = [];
        if (userStore.userSession == null) {
            return;
        }
        const res = await callApi(appStore.roadmapDataApiClient.listEdge({
            sessionId: userStore.userSession,
            roadmapId: this._roadmapId,
        }).response);
        this._edgeList = res.edgeList;
    }

    async loadNodeStateList(targetMemberUserId: string) {
        if (userStore.userSession == null) {
            return;
        }
        this._targetMemberUserId = targetMemberUserId;
        const res = await callApi(appStore.roadmapDataStateApiClient.list({
            sessionId: userStore.userSession,
            roadmapId: this.roadmapId,
            targetMemberUserId: targetMemberUserId,
        }).response);
        this._nodeStateList = res.stateList.sort((a, b) => Number(b.timeStamp - a.timeStamp));
    }

    async onUpdateNode(nodeId: string) {
        if (userStore.userSession == null) {
            return;
        }
        const res = await callApi(appStore.roadmapDataApiClient.getNode({
            sessionId: userStore.userSession,
            roadmapId: this._roadmapId,
            nodeId: nodeId,
        }).response);
        const tmpList = this._nodeList.slice();
        const index = tmpList.findIndex(item => item.nodeId == nodeId);
        if (index == -1) {
            tmpList.push(res.node!);
        } else {
            tmpList[index] = res.node!;
        }
        this._nodeList = tmpList;
    }

    async onRemoveNode(nodeId: string) {
        if (userStore.userSession == null || this.roadmapMode != "edit") {
            return;
        }
        await callApi(
            appStore.roadmapDataApiClient.removeNode({
                sessionId: userStore.userSession,
                roadmapId: roadmapStore.roadmapId,
                nodeId: nodeId
            }).response
        );
        const tmpNodeList = this._nodeList.filter(item => item.nodeId != nodeId);
        this._nodeList = tmpNodeList;
        const tmpEdgeList = this._edgeList.filter(item => !(item.edgeKey?.fromNodeId == nodeId || item.edgeKey?.toNodeId == nodeId));
        this._edgeList = tmpEdgeList;
    }

    async onUpdateEdge(edgeKey: EdgeKey) {
        if (userStore.userSession == null) {
            return;
        }
        const res = await callApi(appStore.roadmapDataApiClient.getEdge({
            sessionId: userStore.userSession,
            roadmapId: this._roadmapId,
            edgeKey: edgeKey,
        }).response);
        const tmpList = this._edgeList.slice();
        const index = tmpList.findIndex(item => (
            item.edgeKey?.fromNodeId == edgeKey.fromNodeId
            && item.edgeKey?.fromHandle == edgeKey.fromHandle
            && item.edgeKey?.toNodeId == edgeKey.toNodeId
            && item.edgeKey?.toHandle == edgeKey.toHandle
        ));
        if (index == -1) {
            tmpList.push(res.edge!);
        } else {
            tmpList[index] = res.edge!;
        }
        this._edgeList = tmpList;
    }

    async onRemoveEdge(edgeKey: EdgeKey) {
        if (userStore.userSession == null || this.roadmapMode != "edit") {
            return;
        }
        await callApi(appStore.roadmapDataApiClient.removeEdge({
            sessionId: userStore.userSession,
            roadmapId: this.roadmapId,
            edgeKey: edgeKey,
        }).response);
        const tmpList = this._edgeList.filter(item => !(
            item.edgeKey?.fromNodeId == edgeKey.fromNodeId
            && item.edgeKey.fromHandle == edgeKey.fromHandle
            && item.edgeKey.toNodeId == edgeKey.toNodeId
            && item.edgeKey.toHandle == edgeKey.toHandle
        ));
        this._edgeList = tmpList;
    }

    async onAddNodeState(nodeId: string, stateId: string) {
        if (userStore.userSession == null || this.roadmapMode != "update") {
            return;
        }
        const res = await callApi(appStore.roadmapDataStateApiClient.get({
            sessionId: userStore.userSession,
            roadmapId: this.roadmapId,
            nodeId: nodeId,
            stateId: stateId,
        }).response);
        const tmpList = this._nodeStateList.slice();
        const index = tmpList.findIndex(item => item.stateId == stateId);
        if (index == -1) {
            tmpList.push(res.state!);
        } else {
            tmpList[index] = res.state!;
        }
        this._nodeStateList = tmpList;
    }

    onRemoveNodeState(nodeId: string, stateId: string) {
        const tmpList = this._nodeStateList.filter(item => !(item.nodeId == nodeId && item.stateId == stateId));
        this._nodeStateList = tmpList;
    }

    //Rag相关配置
    private _ragConfigList = $state([] as RagConfig[]);

    get ragConfigList() {
        return this._ragConfigList;
    }

    private async loadRagConfigList() {
        if (userStore.userSession == null) {
            return;
        }
        const res = await callApi(appStore.roadmapRagApiClient.listConfig({
            sessionId: userStore.userSession,
            roadmapId: this._roadmapId,
        }).response);
        this._ragConfigList = res.configList;
    }

    //资源库相关熟悉
    public resourceStateVersion = $state(0);
}

export const roadmapStore = $state(new RoadmapStore());